package mbp.gui.panels;

import javax.swing.JPanel;
import mbp.base.FeatureType;
import mbp.base.ResourceType;
import mbp.core.Resource;
import mbp.core.ResourceValidation;
import mbp.core.Service;
import mbp.exceptions.InvalidFeatureNameException;
import mbp.exceptions.InvalidFeatureTypeException;
import mbp.exceptions.InvalidFeatureValueException;
import mbp.exceptions.InvalidValueException;
import mbp.gui.base.EachRowEditor;

import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.UIManager;
import java.awt.Color;
import javax.swing.JScrollPane;
import java.awt.Component;
import javax.swing.JButton;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.DefaultCellEditor;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JComboBox;

import org.apache.log4j.Logger;

public class ServiceEditPanel extends JPanel implements ActionListener
{	
	private Service service;
	private JTextField textField;
	private JTextField txtOfferV;
	private JTextField txtRealizeV;
	private JButton btnSave;
	private JComboBox cmbOut;
	private ArrayList<Resource> serviceRcOut; //Lista na zasoby wyjsciowe aktywnego serwisu
	
	private JTable tdOut;
	private JTable tdIn;
	private DefaultTableModel modelOut, modelIn;
	
	private Logger logger = Logger.getLogger(this.getClass());
	private JTextField txtQuantity;


	/**
	 * Create the frame.
	 */
	public ServiceEditPanel() 
	{
		//this.setTitle("Service editor - Loaded service type: " + service.getServiceType().GetServiceTypeName());
		serviceRcOut = new ArrayList<Resource>();
		//setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		//setBounds(100, 100, 704, 321);
		//contentPane = new JPanel();
		//contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		//setContentPane(contentPane);
		//contentPane.setLayout(null);
		
		//JPanel panel_0 = new JPanel();
		setLayout(null);
		setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Service details", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
		setBounds(10, 11, 676, 265);
		//contentPane.add(panel_0);
		
		JScrollPane scrollPane1 = new JScrollPane((Component) null);
		scrollPane1.setBounds(12, 40, 270, 76);
		add(scrollPane1);
		
		modelOut = new DefaultTableModel();
		modelOut.addColumn("Feature Name");
		modelOut.addColumn("Feature Type");
		modelOut.addColumn("Feature Value");
		tdOut = new JTable(modelOut);
		tdOut.setFillsViewportHeight(true);
		scrollPane1.setViewportView(tdOut);
		
		btnSave = new JButton("Save");
		btnSave.setName("SET");
		btnSave.setFont(new Font("Arial", Font.PLAIN, 11));
		btnSave.setBounds(585, 93, 79, 23);
		add(btnSave);
		btnSave.addActionListener(this);
		
		JLabel label = new JLabel("Validity");
		label.setFont(new Font("Dialog", Font.PLAIN, 12));
		label.setBounds(404, 102, 109, 14);
		add(label);
		
		textField = new JTextField("10");
		textField.setBounds(292, 96, 109, 20);
		add(textField);
		
		JLabel label_1 = new JLabel("Out");
		label_1.setBounds(12, 23, 46, 14);
		add(label_1);
		
		cmbOut = new JComboBox();
		cmbOut.setBounds(292, 40, 109, 22);
		add(cmbOut);
		
		JScrollPane scrollPane2 = new JScrollPane();
		scrollPane2.setBounds(12, 145, 652, 100);
		add(scrollPane2);
		
		modelIn = new DefaultTableModel();
		modelIn.addColumn("Index");
		modelIn.addColumn("Type");
		modelIn.addColumn("Condition");
		modelIn.addColumn("Quantity");
		modelIn.addColumn("Term");
		tdIn = new JTable(modelIn);
		tdIn.setFillsViewportHeight(true);
		//tdIn.getColumnModel().getColumn(0).setPreferredWidth(50);
		scrollPane2.setViewportView(tdIn);
		
		JLabel label_2 = new JLabel("In");
		label_2.setBounds(12, 128, 35, 15);
		add(label_2);
		
		txtOfferV = new JTextField();
		txtOfferV.setColumns(10);
		txtOfferV.setBounds(426, 43, 114, 19);
		add(txtOfferV);
		
		txtRealizeV = new JTextField();
		txtRealizeV.setColumns(10);
		txtRealizeV.setBounds(550, 43, 114, 19);
		add(txtRealizeV);
		
		JLabel label_3 = new JLabel("Offer validity");
		label_3.setFont(new Font("Dialog", Font.PLAIN, 12));
		label_3.setBounds(426, 22, 114, 15);
		add(label_3);
		
		JLabel label_4 = new JLabel("Realize term");
		label_4.setFont(new Font("Dialog", Font.PLAIN, 12));
		label_4.setBounds(550, 22, 114, 15);
		add(label_4);
		
		txtQuantity = new JTextField();
		txtQuantity.setBounds(292, 71, 109, 20);
		add(txtQuantity);
		txtQuantity.setColumns(10);
		
		JLabel lblQyantity = new JLabel("Quantity");
		lblQyantity.setFont(new Font("Dialog", Font.PLAIN, 12));
		lblQyantity.setBounds(404, 77, 79, 14);
		add(lblQyantity);
		
		cmbOut.addItemListener(new ItemListener() {
			
			@Override
			public void itemStateChanged(ItemEvent arg0) {
				int index = cmbOut.getSelectedIndex();
				loadresourceOut(serviceRcOut, index);
			}
		});
		
	}
	
	public void loadService(Service srv)
	{
		this.service = srv;
		int rowsCount = 0;
		//System.out.println("Service type name: " + srv.getServiceType().GetServiceTypeName());
		//ArrayList<ResourceType> types_in = (ArrayList<ResourceType>) srv.getServiceType().getResourceTypesIn();
		ArrayList<Resource> types_out = (ArrayList<Resource>) srv.getResourcesOut();
		
		ArrayList<ResourceValidation> valInAdvance = srv.getResourcesIn(0);
		ArrayList<ResourceValidation> valInStuff = srv.getResourcesIn(1);
		ArrayList<ResourceValidation> valInPay = srv.getResourcesIn(2);
		
		/**
		 * Wyczyszczenie tabeli
		 */
		for( int i = modelIn.getRowCount() - 1; i >= 0; i-- )
		{
		    modelIn.removeRow(i);
		}
		
		//Zasoby zaliczka
		for(int i = 0; i<valInAdvance.size(); i++)
		{
			modelIn.insertRow(i, new Object[]{"advance", 
					valInAdvance.get(i).getType().getResourceTypeName(), 
					srv.getResourcesIn(0).get(i).getCondition(),
					srv.getResourcesIn(0).get(i).getQuantity().toString(),
					"-"});
		}
		rowsCount = valInAdvance.size();
		
		//Zasoby towar
		for(int i = 0; i<valInStuff.size(); i++)
		{
			modelIn.insertRow(i+rowsCount, new Object[]{"stuff", 
					valInStuff.get(i).getType().getResourceTypeName(), 
                    srv.getResourcesIn(1).get(i).getCondition(),
                    srv.getResourcesIn(1).get(i).getQuantity().toString(),
                    srv.getResourcesInDeliveryTrems().get(i).toString()});
			
		}
		rowsCount = rowsCount + valInStuff.size();
		
		//zasoby zaplata
		for(int i = 0; i<valInPay.size(); i++)
		{
			modelIn.insertRow(i+rowsCount, new Object[]{"pay", 
					valInPay.get(i).getType().getResourceTypeName(), 
                    srv.getResourcesIn(2).get(i).getCondition(),
                    srv.getResourcesIn(2).get(i).getQuantity().toString(),
                    "-"});
			
		}
		
		//for(int i = 0; i<types_in.size(); i++)
		//{
		//	modelIn.insertRow(i, new Object[]{i, types_in.get(i).GetResourceTypeName(), srv.getResourcesIn(-1).get(i).getCondition()});
		//}
		
		cmbOut.removeAllItems();
		serviceRcOut = new ArrayList<Resource>();
		for(int i = 0; i<types_out.size(); i++)
		{
			//cmbOut.addItem(types_out.get(i).GetType().GetResourceTypeName());
			serviceRcOut.add(types_out.get(i));
			cmbOut.addItem(types_out.get(i).getType().getResourceTypeName());
		}
		
		txtOfferV.setText(srv.getOfferValidTerm().toString());
		txtRealizeV.setText(srv.getServiceRealizeTerm().toString());
		
		//tdIn.getColumnModel().getColumn(0).setMinWidth(60);
		//tdIn.getColumnModel().getColumn(0).setMaxWidth(60);
		//tdIn.getColumnModel().getColumn(1).setMinWidth(70);
		//tdIn.getColumnModel().getColumn(1).setMaxWidth(100);
		tdIn.getColumnModel().getColumn(2).setMinWidth(450);
		tdIn.getColumnModel().getColumn(2).setMaxWidth(450);
	}
	
	
	public void loadresourceOut(ArrayList<Resource> rcOutList, int index)
	{
		if(index == -1)return;
		
		int rowsCount = 0;
		/**
		 * Wyczyszczenie tabeli
		 */
		for( int i = modelOut.getRowCount() - 1; i >= 0; i-- )
		{
		    modelOut.removeRow(i);
		}
		
		Resource rcOut = rcOutList.get(index);
		ResourceType resType = rcOut.getType();
		
		/**
		 * Utworzenie tabeli JTable dt pozwalajecej wrowadzic wartosci cech utworzonego zasobu
		 */
		Iterator it = rcOut.getType().getFeaturesCollection().keySet().iterator();
		while (it.hasNext()) 
		{
			String key = (String)it.next();
			//System.out.println("f: " + key);
			//rowsCount = dt.getRowCount();
			try
			{
				FeatureType type = rcOut.getFeatureType(key);
				Object ob = rcOut.getFeatureValue(key);
				if(ob==null)
				{
					modelOut.insertRow(rowsCount, new Object[]{key,  rcOut.getFeatureType(key), null});
				}
				else
				{
					switch(type)
					{
					case INT:
						modelOut.insertRow(rowsCount, new Object[]{key,  rcOut.getFeatureType(key), ((Integer)ob).toString()});						
						break;
					case FLOAT:
						modelOut.insertRow(rowsCount, new Object[]{key,  rcOut.getFeatureType(key), ((Float)ob).toString()});
						break;
					default:
						modelOut.insertRow(rowsCount, new Object[]{key,  rcOut.getFeatureType(key), ob.toString()});
						break;
					}
				}
				
				rowsCount++;
			}
			catch (InvalidFeatureNameException ex)
			{
				//logger.error("InvalidFeatureNameException", ex);
			} 
		}
		
		/**
		 * DLA TYPOW ENUM
		 * Modyfikacja komorek tabeli (danego wiersza) aby mozna bylo wyswietlic obiekt JComboBox
		 */
		EachRowEditor rowEditor = new EachRowEditor(tdOut);
		for(int i = 0; i<tdOut.getRowCount(); i++)
		{
			if(tdOut.getValueAt(i, 1) == FeatureType.ENUM)
			{
				/**
				 * Utworzenie obiektu JComboBox wartosci enum przylkadowego typu
				 * Obiekt ten zostanie umieszczony w tabeli
				 */
				JComboBox cmbTypesV = new JComboBox();
					String[] ev = resType.getEnumTypes().get((String)tdOut.getValueAt(i, 0)).getArray();
					
					for(String v: ev)
					{
						cmbTypesV.addItem(v);
					}
				rowEditor.setEditorAt(i, new DefaultCellEditor(cmbTypesV));
							
			}
			tdOut.getColumn("Feature Value").setCellEditor(rowEditor);
		}
		
		txtQuantity.setText(rcOut.getQuantity().toString());
	}
	
	/**
	 * Ustawienie parametrow uslugi
	 */
	public void setService()
	{
		//ArrayList<ResourceValidation> inList = service.getResourcesIn(-1);
		ArrayList<ResourceValidation> valInAdvance = service.getResourcesIn(0);
		ArrayList<ResourceValidation> valInStuff = service.getResourcesIn(1);
		ArrayList<ResourceValidation> valInPay = service.getResourcesIn(2);
		int ai = 0;
		int si = 0;
		int pi = 0;
		
		ArrayList<Integer> stuffValidTU = new ArrayList<Integer>();
		
		ArrayList<Resource> outList = service.getResourcesOut();
		
		//Ustawianie zakresu zasob�w wej�ciowych zaleznie od przeznaczenia - zalicka / towar / zapata 
		for(int i = 0; i<modelIn.getRowCount(); i++)
		{
			String point = (String) modelIn.getValueAt(i, 0);
			char p = point.charAt(0);
			
			switch(p)
			{
			case 'a':
				valInAdvance.get(ai).setCondition((String) modelIn.getValueAt(i, 2));
				valInAdvance.get(ai).setQuantity(Integer.parseInt((String) modelIn.getValueAt(i, 3)));
				ai++;
				break;
			case 's':
				valInStuff.get(si).setCondition((String) modelIn.getValueAt(i, 2));
				valInStuff.get(si).setQuantity(Integer.parseInt((String) modelIn.getValueAt(i, 3)));
				stuffValidTU.add(Integer.parseInt((String) modelIn.getValueAt(i, 4)));
				si++;
				break;
			case 'p':
				valInPay.get(pi).setCondition((String) modelIn.getValueAt(i, 2));
				valInPay.get(pi).setQuantity(Integer.parseInt((String) modelIn.getValueAt(i, 3)));
				pi++;
				break;
			}
			
		}
		
		service.setResourcesInDeliveryTrems(stuffValidTU);
		service.setServiceRealizeTerm(Integer.parseInt(txtRealizeV.getText()));
		service.setOfferValidTerm(Integer.parseInt(txtOfferV.getText()));
		
		//Ustawienie warto�ci cech wzorcowych zasob�w wyj�ciowych
		Resource rc = serviceRcOut.get(cmbOut.getSelectedIndex());
		try {
			rc.setQuantity(Integer.parseInt( txtQuantity.getText()));
		} catch (NumberFormatException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (InvalidValueException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		for(int i = 0; i<modelOut.getRowCount(); i++)
		{	
			try {
				
				FeatureType type = rc.getFeatureType((String) modelOut.getValueAt(i, 0));
				switch(type)
				{
				case INT:
					rc.setFeatureValue((String) modelOut.getValueAt(i, 0), Integer.parseInt((String) modelOut.getValueAt(i, 2)));										
					break;
				case FLOAT:
					rc.setFeatureValue((String) modelOut.getValueAt(i, 0), Float.parseFloat((String) modelOut.getValueAt(i, 2)));
					break;
				case ENUM:
					rc.setFeatureValue((String) modelOut.getValueAt(i, 0), (String)modelOut.getValueAt(i, 2));
				default:				
					break;
				}
				
				
			} catch (InvalidFeatureNameException e) {
				// TODO Auto-generated catch block
				logger.error("InvalidFeatureNameException", e);
			} catch (InvalidFeatureTypeException e) {
				// TODO Auto-generated catch block
				logger.error("InvalidFeatureTypeException", e);
			} catch (InvalidFeatureValueException e) {
				// TODO Auto-generated catch block
				logger.error("InvalidFeatureValueExceptio", e);
			} catch (Exception e) {
				logger.error("Exception", e);
			}
			//for(int j = 0; j <)
		}	
	}

	@Override
	public void actionPerformed(ActionEvent e) 
	{
		if(e.getSource() == btnSave)
		{
			setService();
		}
		
	}
}
